import ffmpegPath from '@ffmpeg-installer/ffmpeg'
import ffproPath from '@ffprobe-installer/ffprobe'
import { BrowserWindow, IpcMainInvokeEvent } from 'electron'
import ffmpeg from 'fluent-ffmpeg'
import { existsSync, renameSync } from 'node:fs'
import path from 'node:path'
import { CompressOptions, MainProcessNoticeType } from '../renderer/src/types'

ffmpeg.setFfmpegPath(ffmpegPath.path.replace('app.asar', 'app.asar.unpacked'))
ffmpeg.setFfprobePath(ffproPath.path.replace('app.asar', 'app.asar.unpacked'))

export default class Ffmpeg {
  constructor(
    // private event?: IpcMainInvokeEvent,
    private options?: CompressOptions,
    private ffmpeg?: ffmpeg.FfmpegCommand,
    private window?: BrowserWindow
  ) {}
  init(event: IpcMainInvokeEvent, options: CompressOptions) {
    this.options = options
    this.window = BrowserWindow.fromWebContents(event.sender)!
    this.ffmpeg = ffmpeg(this.options.file.path)
    return this
  }
  processEvent(progress) {
    // console.log('progress', progress.percent)
    this.window!.webContents.send('mainProcessNotice', MainProcessNoticeType.PROGRESS, progress.percent, this.options!.file.path)
  }
  error(err) {
    this.window!.webContents.send('mainProcessNotice', MainProcessNoticeType.ERROR, { message: err.message, file: this.options!.file }, this.options!.file.path)
  }
  end() {
    renameSync(this.tempFilePath(), this.getFilePath())
    this.window!.webContents.send('mainProcessNotice', MainProcessNoticeType.END, '', this.options!.file.path)
  }
  private getFilePath() {
    const info = path.parse(this.options!.file.name)
    return path.join(this.options!.directory, info.name + '-' + this.options!.size + '-' + this.options!.fps + info.ext)
  }
  private tempFilePath() {
    return path.join(this.options!.directory, '.temp')
  }
  private validate() {
    if (!existsSync(this.options!.directory)) {
      this.window!.webContents.send('mainProcessNotice', MainProcessNoticeType.DIRECTORY_CHECK, '保存目标目录不存在', this.options!.file.path)
      return false
    }
    if (existsSync(this.getFilePath())) {
      this.window!.webContents.send('mainProcessNotice', MainProcessNoticeType.FILE_IS_EXISTS, '目标视频文件已存在', this.options!.file.path)
      return false
    }
    return true
  }
  stop() {
    try {
      this.ffmpeg!.kill('SIGKILL')
      this.window!.webContents.send('mainProcessNotice', MainProcessNoticeType.STOP, '', this.options!.file.path)
    } catch (error) {
      /* empty */
    }
  }
  run() {
    if (!this.validate()) return
    this.ffmpeg!.fps(this.options!.fps)
      .size(this.options!.size)
      .format('mp4')
      .videoCodec('libx264')
      .videoBitrate(this.options!.videoBitrate * 50)
      .on('progress', this.processEvent.bind(this))
      .on('error', this.error.bind(this))
      .on('end', this.end.bind(this))
      .save(this.tempFilePath())
  }
}
